﻿using BCCommon;
using BCCommon.Enums;
using BCData.CRM.EnterpriseInfomation;
using BCDto.CRM.EnterpriseInfomation;
using BCEntity.CRM.EnterpriseInfomation;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Text.RegularExpressions;
using BCDto.Tools;
using System.Threading.Tasks;

namespace BCService.CRM.EnterpriseInfomation
{
    public class EnterpriseInfomationService : IEnterpriseInfomationService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IRedisService redisService;
        private readonly IEnterpriseInfomationData enterpriseInfomationData;
        private readonly string key = string.Format("{0}", EntityNameConst.EnterpriseInfomationEntity);

        public EnterpriseInfomationService(IDatabaseContext databaseContext,
            IRedisService redisService,
            IEnterpriseInfomationData enterpriseInfomationData)
        {
            this.databaseContext = databaseContext;
            this.redisService = redisService;
            this.enterpriseInfomationData = enterpriseInfomationData;
        }

        #region 检查企业信息是否存在
        public bool Exists(long enterpriseInfomationId)
        {
            return this.enterpriseInfomationData.Exists(enterpriseInfomationId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加企业信息
        public EnterpriseInfomationDto Add(EnterpriseInfomationRequestDto requestDto)
        {
            var entity = requestDto.As<EnterpriseInfomationEntity>();

            var result = this.enterpriseInfomationData.Add(entity).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
            return result.As<EnterpriseInfomationDto>();
        }
        #endregion

        #region 修改企业信息
        public EnterpriseInfomationDto Update(EnterpriseInfomationPutDto putDto)
        {
            if (!this.Exists(putDto.EnterpriseInfomationId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = putDto.As<EnterpriseInfomationEntity>();
            var result = this.enterpriseInfomationData.Update(entity).GetAwaiter().GetResult().As<EnterpriseInfomationDto>();
            this.redisService.DeleteMultipleKey(key, false);
            return result;
        }
        #endregion

        #region 删除企业信息
        public bool Delete(long enterpriseInfomationId)
        {
            if (!this.Exists(enterpriseInfomationId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            var result = this.enterpriseInfomationData.Delete(enterpriseInfomationId).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
            return result;
        }
        #endregion

        #region 获取企业信息
        public EnterpriseInfomationDto Get(long enterpriseInfomationId)
        {
            string cacheKey = this.redisService.GetKey(key, enterpriseInfomationId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.enterpriseInfomationData.GetEntity(enterpriseInfomationId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<EnterpriseInfomationDto>();
        }
        #endregion

        #region 获取企业信息列表
        public IEnumerable<EnterpriseInfomationDto> GetList()
        {
            var result = this.redisService.TryGet(key, () =>
            {
                return this.enterpriseInfomationData.GetList().GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<EnterpriseInfomationDto>>();
        }
        #endregion

        #region 获取企业信息分页
        public PageableList<EnterpriseInfomationDto> Query(DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.enterpriseInfomationData.Query(start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<EnterpriseInfomationDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<EnterpriseInfomationDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }

        #endregion

        #region 导入

        public ImportResultDto ImportEnterpriseFile(string sourceType, string filePath)
        {
            DataTable table = OfficeHelper.ReadExcelToDataTable(filePath);

            List<EnterpriseInfomationEntity> list = new List<EnterpriseInfomationEntity>();
            List<string> errorMessages = new List<string>();
            if (sourceType == "TianYanCha")
            {
                list.AddRange(this.GetTianyanchaImportData(table, ref errorMessages));
            }
            else if(sourceType == "GeneralTemplate") 
            {
                list.AddRange(this.GetGeneralTemplateImportData(table, ref errorMessages));
            }
            if (!list.Any())
            {
                throw new ArgumentException("没有需要添加的");
            }
            List<EnterpriseInfomationEntity> addList = new List<EnterpriseInfomationEntity>();
            ParallelLoopResult loopResult = Parallel.ForEach(list, (item) =>
             {
                 if (!string.IsNullOrWhiteSpace(item.SocialUniformCode) && !this.enterpriseInfomationData.ExistsBySocialUniformCode(item.SocialUniformCode).GetAwaiter().GetResult())
                 {
                     addList.Add(item);
                 }
                 else if (!this.enterpriseInfomationData.ExistsByCompanyName(item.CompanyName).GetAwaiter().GetResult())
                 {
                     addList.Add(item);
                 }
             });
            if (loopResult.IsCompleted)
            {
                this.enterpriseInfomationData.Import(addList);
            }
            ImportResultDto result = new ImportResultDto();
            result.SuccessCount = addList.Count;
            result.ErrorMessages = errorMessages;
            return result;
        }

        private List<EnterpriseInfomationEntity> GetTianyanchaImportData(DataTable table, ref List<string> errorMessages)
        {
            List<string> exceptionMessage = new List<string>();
            List<EnterpriseInfomationEntity> result = new List<EnterpriseInfomationEntity>();
            for (int i = 0; i < table.Rows.Count; i++)
            {
                bool allowerAdd = true;
                
                var row = table.Rows[i];
                if (string.IsNullOrWhiteSpace(row[0].ToString()))
                {
                    continue;
                }
                var entity = new EnterpriseInfomationEntity();
                entity.CompanyName = row[0].ToString();
                if(entity.CompanyName.IndexOf("单位名称")>-1)
                {
                    continue;
                }
                entity.Corporation = row[1].ToString();
                entity.RegisteredCapitalStr = row[2].ToString();
                Regex regex = new Regex("([0-9]*\\.[0-9]+|[0-9]+)");
                string registeredCapitalStr = string.Empty;
                if (regex.IsMatch(entity.RegisteredCapitalStr))
                {
                    Match match = regex.Match(entity.RegisteredCapitalStr);
                    registeredCapitalStr = match.Value;
                }
                if (!string.IsNullOrWhiteSpace(registeredCapitalStr))
                {
                    string unit = row[2].ToString().Replace("人民币", "").IndexOf("万") > -1 ? "万" : "";
                    if (unit == "万")
                    {
                        registeredCapitalStr = registeredCapitalStr + "0000";
                    }
                    if (!decimal.TryParse(registeredCapitalStr, out decimal registeredCapital))
                    {
                        exceptionMessage.Add(string.Format("第{0}行,注册资金列转换出错!", i));
                        allowerAdd = false;
                    }
                    entity.RegisteredCapital = registeredCapital;
                }

                if (!DateTime.TryParse(row[3].ToString(), out DateTime registeredDate))
                {
                    exceptionMessage.Add(string.Format("第{0}行,注册日期列转换出错!", i));
                    allowerAdd = false;
                }
                entity.RegisteredDate = registeredDate;
                entity.ManagementForms = row[4].ToString();
                entity.ProvinceName = row[5].ToString();
                entity.CityName = row[6].ToString();
                entity.CountyName = row[7].ToString();
                entity.CompanyType = row[8].ToString();
                entity.SocialUniformCode = row[9].ToString();
                entity.TaxIdNumber = row[10].ToString();
                entity.RegisteredNo = row[11].ToString();
                entity.OrganizationCode = row[12].ToString();
                entity.PublicCompanyPhone = row[13].ToString();
                entity.PublicCompanyPhoneMore = row[14].ToString();
                if (!int.TryParse(row[15].ToString(), out int insuranceSchemeNumber))
                {
                    exceptionMessage.Add(string.Format("第{0}行,参保人数列转换出错!", i));
                    allowerAdd = false;
                }
                entity.InsuranceSchemeNumber = insuranceSchemeNumber;
                entity.IndustryCategoryName = row[16].ToString();
                entity.PublicCompanyAddress = row[17].ToString();
                entity.PublicCompanyWebsite = row[18].ToString();
                entity.PublicCompanyEmail = row[19].ToString();
                entity.BusinessScope = row[20].ToString();
                if (allowerAdd)
                {
                    result.Add(entity);
                }
            }
            errorMessages = exceptionMessage;
            return result;
        }

        private List<EnterpriseInfomationEntity> GetGeneralTemplateImportData(DataTable table, ref List<string> errorMessages)
        {
            List<string> exceptionMessage = new List<string>();
            List<EnterpriseInfomationEntity> result = new List<EnterpriseInfomationEntity>();
            for (int i = 0; i < table.Rows.Count; i++)
            {
                bool allowerAdd = true;

                var row = table.Rows[i];
                if (string.IsNullOrWhiteSpace(row[0].ToString()))
                {
                    continue;
                }
                var entity = new EnterpriseInfomationEntity();
                entity.CompanyName = row[0].ToString();
                entity.Corporation = row[2].ToString();
                entity.RegisteredCapitalStr = string.Empty; //row[2].ToString();
                Regex regex = new Regex("([0-9]*\\.[0-9]+|[0-9]+)");
                string registeredCapitalStr = string.Empty;
                if (regex.IsMatch(entity.RegisteredCapitalStr))
                {
                    Match match = regex.Match(entity.RegisteredCapitalStr);
                    registeredCapitalStr = match.Value;
                }
                if (!string.IsNullOrWhiteSpace(registeredCapitalStr))
                {
                    string unit = row[2].ToString().Replace("人民币", "").IndexOf("万") > -1 ? "万" : "";
                    if (unit == "万")
                    {
                        registeredCapitalStr = registeredCapitalStr + "0000";
                    }
                    if (!decimal.TryParse(registeredCapitalStr, out decimal registeredCapital))
                    {
                        exceptionMessage.Add(string.Format("第{0}行,注册资金列转换出错!", i));
                        allowerAdd = false;
                    }
                    entity.RegisteredCapital = registeredCapital;
                }

                if (!DateTime.TryParse(row[4].ToString(), out DateTime registeredDate))
                {
                    exceptionMessage.Add(string.Format("第{0}行,注册日期列转换出错!", i));
                    allowerAdd = false;
                }
                entity.RegisteredDate = registeredDate;
                entity.ManagementForms = "在业"; //row[4].ToString();
                List<string> addressList = this.AddressSplit(row[6].ToString());
                entity.ProvinceName = addressList[0];
                entity.CityName = addressList[1];
                entity.CountyName = addressList[2];
                entity.CompanyType = string.Empty;
                entity.SocialUniformCode = row[1].ToString();
                entity.TaxIdNumber = row[1].ToString();
                entity.RegisteredNo = row[1].ToString();
                entity.OrganizationCode = row[1].ToString();
                entity.PublicCompanyPhone = string.Empty; //row[13].ToString();
                entity.PublicCompanyPhoneMore = row[3].ToString();
                //if (!int.TryParse(row[15].ToString(), out int insuranceSchemeNumber))
                //{
                //    exceptionMessage.Add(string.Format("第{0}行,参保人数列转换出错!", i));
                //    allowerAdd = false;
                //}
                entity.InsuranceSchemeNumber = null; //insuranceSchemeNumber;
                entity.IndustryCategoryName = string.Empty; //row[16].ToString();
                entity.PublicCompanyAddress = row[6].ToString();
                entity.PublicCompanyWebsite = string.Empty; //row[18].ToString();
                entity.PublicCompanyEmail = string.Empty; //row[19].ToString();
                entity.BusinessScope = string.Empty; //row[20].ToString();
                if (allowerAdd)
                {
                    result.Add(entity);
                }
            }
            errorMessages = exceptionMessage;
            return result;
        }
        /// <summary>
        /// 地址拆分
        /// </summary>
        /// <param name="address">地址</param>
        /// <returns></returns>
        private List<string> AddressSplit(string address)
        {
            List<string> addressList = new List<string>();

            string provinceName = string.Empty;
            string cityName = string.Empty;
            string countyName = string.Empty;

            string[] municipalities = new string[] { "北京市", "天津市", "上海市", "重庆市" };

            if (address.IndexOf("省") > -1)
            {
                provinceName = address.Substring(0, address.IndexOf("省") + 1);
                address = address.Replace(provinceName, "");
            }
            else if (address.IndexOf("自治区") > -1)
            {
                provinceName = address.Substring(0, address.IndexOf("自治区") + 3);
                address = address.Replace(provinceName, "");
            }
            else if (address.IndexOf("市") > -1)
            {
                string templateCityName = address.Substring(0, address.IndexOf("市") + 1);
                if (municipalities.Contains(templateCityName))
                {
                    provinceName = templateCityName;
                    cityName = templateCityName;
                    address = address.Replace(provinceName, "");
                }
            }

            addressList.Add(provinceName);

            if (address.IndexOf("市") > -1)
            {
                cityName = address.Substring(0, address.IndexOf("市") + 1);
                address = address.Replace(cityName, "");
            }
            else if (address.IndexOf("盟") > -1)
            {
                cityName = address.Substring(0, address.IndexOf("盟") + 1);
                address = address.Replace(cityName, "");
            }
            else if (address.IndexOf("自治州") > -1)
            {
                cityName = address.Substring(0, address.IndexOf("自治州") + 3);
                address = address.Replace(cityName, "");
            }
            else if (address.IndexOf("地区") > -1)
            {
                cityName = address.Substring(0, address.IndexOf("地区") + 2);
                address = address.Replace(cityName, "");
            }
            else if (address.IndexOf("林区") > -1)
            {
                cityName = address.Substring(0, address.IndexOf("林区") + 2);
                address = address.Replace(cityName, "");
            }

            addressList.Add(cityName);

            if (address.IndexOf("区") > -1)
            {
                countyName = address.Substring(0, address.IndexOf("区") + 1);
                address = address.Replace(countyName, "");
            }
            else if (address.IndexOf("县") > -1)
            {
                countyName = address.Substring(0, address.IndexOf("县") + 1);
                address = address.Replace(countyName, "");
            }
            else if(address.IndexOf("旗") > -1)
            {
                countyName = address.Substring(0, address.IndexOf("旗") + 1);
                address = address.Replace(countyName, "");
            }
            else if (address.IndexOf("海域") > -1)
            {
                countyName = address.Substring(0, address.IndexOf("海域") + 2);
                address = address.Replace(countyName, "");
            }
            addressList.Add(countyName);
            return addressList;
        }
        #endregion
    }
}